﻿//
// Copyright (c) 2024 BPer
//


#include <bperutil/sys/BPerSysMessageHandle.h>

#include <bperutil/sys/BPerLog.h>
#include <bperutil/sys/BPerThread.h>
#include <bperutil/BPerAvInfoType.h>

void bPer_post_message(int32_t st, int32_t uid, BPerSysMessageI *mhandle,void* user) {
	if (BPerSysMessageHandle::m_instance)
		BPerSysMessageHandle::m_instance->putMessage(mhandle, st, uid, 0,user);
}
void bPer_post_state_message(int32_t st, int32_t uid, int32_t handleState,BPerSysMessageI *mhandle) {
	if (BPerSysMessageHandle::m_instance)
		BPerSysMessageHandle::m_instance->putMessage(mhandle, st, uid,
				handleState);
}
void bPer_post_userMessage(int32_t st, int32_t uid,BPerSysMessageI *mhandle,void* user){
    if (BPerSysMessageHandle::m_instance)
        BPerSysMessageHandle::m_instance->putMessage(mhandle, st, uid, 0);
}
BPerSysMessageHandle::BPerSysMessageHandle() {
	m_loop = BPerFalse;
	m_isStart = BPerFalse;
	bPer_thread_mutex_init(&m_mutex, NULL);
	bPer_thread_mutex_init(&m_lock, NULL);
	bPer_thread_cond_init(&m_cond_mess, NULL);
	m_waitState = BPerFalse;
	m_receive=NULL;
	if (m_instance == NULL)
		m_instance = this;
}

BPerSysMessageHandle::~BPerSysMessageHandle() {

	if (m_isStart) {
		stop();
		while (m_isStart) {
			bPer_usleep(1000);
		}
	}
	m_instance = NULL;
	bPer_thread_mutex_destroy(&m_mutex);
	bPer_thread_mutex_destroy(&m_lock);
	bPer_thread_cond_destroy(&m_cond_mess);

}
BPerSysMessageHandle *BPerSysMessageHandle::m_instance = NULL;
void BPerSysMessageHandle::run() {
	m_isStart = BPerTrue;
    startLoop();
	m_isStart = BPerFalse;
}
void BPerSysMessageHandle::stop() {
	stopLoop();

}
void BPerSysMessageHandle::stopLoop() {
	m_loop = BPerFalse;
	//bPer_thread_mutex_unlock(&m_lock);
	if(m_waitState){
		bPer_thread_mutex_lock(&m_lock);
		bPer_thread_cond_signal(&m_cond_mess);
		bPer_thread_mutex_unlock(&m_lock);

	}
}

void BPerSysMessageHandle::putMessage(BPerSysMessageI *handle, int32_t pst,
        int32_t puid, int32_t handleState,void* user) {
	if(!m_loop) return;

	BPerSysMessage* mes=new BPerSysMessage();

	mes->uid = puid;
	mes->messageId = pst;
	mes->handleState = handleState;
	mes->handle = handle;
    mes->user=user;
    bPer_thread_mutex_lock(&m_mutex);
	m_sysMessages.push_back(mes);
	bPer_thread_mutex_unlock(&m_mutex);
	mes=NULL;

	if(m_waitState){
		bPer_thread_mutex_lock(&m_lock);
		bPer_thread_cond_signal(&m_cond_mess);
		bPer_thread_mutex_unlock(&m_lock);
	}
}

void BPerSysMessageHandle::startLoop() {
   m_loop = 1;

   bPer_thread_mutex_unlock(&m_lock);
    bPer_thread_mutex_lock(&m_lock);

    while (m_loop) {

        m_waitState=BPerTrue;
        bPer_thread_cond_wait(&m_cond_mess, &m_lock);
        m_waitState=BPerFalse;

        while (m_sysMessages.size()>0) {
            handleMessage(m_sysMessages.front());
            m_sysMessages.front()->handle = NULL;
            delete m_sysMessages.front();
            m_sysMessages.front() = NULL;
            bPer_thread_mutex_lock(&m_mutex);
            m_sysMessages.erase(m_sysMessages.begin());
            bPer_thread_mutex_unlock(&m_mutex);
        }

    }
    bPer_thread_mutex_unlock(&m_lock);
}

